/*
    Copyright 2010 Patrik Jonsson, sunrise@familjenjonsson.org

    This file is part of Sunrise.

    Sunrise is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    Sunrise is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Sunrise.  If not, see <http://www.gnu.org/licenses/>.

*/

/** \file arepo-util.h 

    A few short utility functions for dealing with Arepo data. There
    are not in mcrx-arepo.h because they are meant to be inlined and
    need the Arepo header files. */

// $Id$

#ifndef __arepo_util__
#define __arepo_util__

#ifdef WITH_AREPO

#include "blitz-defines.h"
#include "blitz/tinyvec.h"

// KLUDGE: we don't need these two here but they are included by arepo
// and they won't compile in C-linkage mode
#include "mpi.h"
#include "gmp.h"
extern "C" {
#include "proto.h"
#include "voronoi.h"
}

namespace arepo {
  /// Sets the point in the Arepo DP array to the specified
  /// vec3d. Converts to internal arepo units.
  inline void set_point(const mcrx::vec3d& p, int pp, bool si=true) {
    point* pptr=&Mesh.DP[pp];
    pptr->x = p[0]/lcon; pptr->y = p[1]/lcon;   pptr->z = p[2]/lcon;
    if(si)
      set_integers_for_point(&Mesh, pp);
  }

  /// Sets the Arepo point to the specified
  /// vec3d. Converts to internal arepo units.
  inline void set_point(const mcrx::vec3d& p, point& pptr, bool si=true) {
    pptr.x = p[0]/lcon; pptr.y = p[1]/lcon;   pptr.z = p[2]/lcon;
    if(si) 
      set_integers_for_pointer(&pptr);
  }

  /// Converts the point in the Arepo DP array to a vec3d, converting
  /// to specified length units.
  inline mcrx::vec3d get_point(const point& pptr) {
    return mcrx::vec3d(pptr.x, pptr.y, pptr.z)*lcon;
  }
  
  /// Converts the point in the Arepo DP array to a vec3d, converting
  /// to specified length units.
  inline mcrx::vec3d get_point(const int p) {
    return mcrx::vec3d(Mesh.DP[p].x, Mesh.DP[p].y, Mesh.DP[p].z)*lcon;
  }

  /// Returns true if the mesh point DP[dp_idx] is a valid mesh cell
  /// with hydro quantities.
  inline bool valid_cell(int dp_idx) {
    return Mesh.DP[dp_idx].index>=0 && Mesh.DP[dp_idx].index<N_gas;};

  extern tessellation* T;
};

#endif
#endif
